import * as THREE from "../../three/build/three.module.js";
import {MyMaterial} from "./mymaterial.js"
import {AnimateEvents} from "./animateevents.js"



class AreaData{
    name;
    properties; // 地图信息, 
    describe; // 描述的信息, 比如人口,gdp...
    describeUnit; // 计量单位, 比如人口: 万人
    mesh;
    lineMesh;
    titleMesh;

    isSelected = false;
    isMouseHover = false;
    isUseCircle = false;
    height = 0.2;

    constructor(properties){
        // this.adcode = properties.adcode;
        // this.name = properties.name;
        // this.center = properties.center;
        // this.centroid = properties.centroid;
        // this.childrenNum = properties.childrenNum;
        // this.level = properties.level;
        // this.subFeatureIndex = properties.subFeatureIndex;
        // this.acroutes = properties.acroutes;
        // this.parent = properties.parent;
        this.properties = properties;
        this.name = this.properties.name;
        this.titleMesh = UI.SetTitle(this);
    }
    set IsSelected( val ){
        this.isSelected = val;
        this.updateMaterial(); 
    }
    get IsSelected(){
        return this.isSelected;
    }
    set IsMouseHover( val ){
        this.isMouseHover = val;
        this.updateMaterial();
    }
    get IsMouseHover(){
        return this.isMouseHover;
    }
    set IsUseCircle( val ){
        this.isUseCircle = val;

        let uniforms = this.mesh.children[0].material.uniforms;

        console.log(`cccc`,this.properties.center);
        uniforms._useCircle.value = val;

        this.updateMaterial();
    }
    get IsUseCircle(){
        return this.isUseCircle;
    }
    set Height( val ){
        this.height = val;
        let h = val;
        this.lineMesh.scale.z = h;
        this.mesh.scale.z = h;
        // console.log(`this.titleMesh.position.y`,this.titleMesh.position.y);
        this.titleMesh.position.y = h;
    }
    get Height(){
        return this.height;
    }

    setMesh(mesh, lineMesh){
        this.mesh = mesh;
        this.lineMesh = lineMesh;
        mesh.data = this;
    }
    setMaterial(material){
        this.mesh.children.map(function(mesh){
            mesh.material = material;
        })
    }

    updateMaterial(){
        let _ = this;
        let uniforms = _.mesh.children[0].material.uniforms;
        uniforms._center.value.set(this.properties.center[0],this.properties.center[1]);
        uniforms._isTop.value = _.IsSelected || _.IsMouseHover;
        _.lineMesh.children[0].children[1].material.transparent = uniforms._isTop.value;
        // TODO: 暂时注释
        // if( this.isMouseHover &&  this.isSelected) {this.setMaterial(MyMap.materialSelected); return;}
        // if( this.isMouseHover && !this.isSelected) {this.setMaterial(MyMap.materialMouseHover); return;}
        // if(!this.isMouseHover &&  this.isSelected) {this.setMaterial(MyMap.materialSelected); return;}
        // if(!this.isMouseHover && !this.isSelected) {this.setMaterial(MyMap.materialDefault); return;}
    }

    click(){
        
    }
    select(){
        UI.SetUIContext(this);
        MyMap.areaDataSelected = this;

        this.IsSelected = true;
        this.IsUseCircle = true;
        this.updateMaterial();
    }
    unselect(){
        this.IsSelected = false;
        this.IsUseCircle = false;
    }
    mouseEnter(){
        this.IsMouseHover = true;
    }
    mouseHover(){
    }
    mouseLeave(){
        this.IsMouseHover = false;
    }

}
class MyMap{
    // static scene = null;
    // static materialDefault = new THREE.MeshBasicMaterial({color:0xcc0000});
    static materialDefault(){
        return MyMaterial.AreaMaterial(window.innerWidth / window.innerHeight);
    } 
    // static materialDefault = MyMaterial.CreateMaterial();
    // static materialMouseHover = new THREE.MeshBasicMaterial({color:0xcc8866});
    // static materialSelected = MyMaterial.CreateMaterial(window.innerWidth / window.innerHeight);
    // static materialSelected_And_MouseHover = new THREE.MeshBasicMaterial({color:0x668866});
    // static materialShow = MyMaterial.CreateMaterial();
    static materialLineTop(){
        // return new THREE.LineBasicMaterial({color:0xffff00,depthFunc:THREE.AlwaysDepth,transparent:false})
        return new THREE.LineBasicMaterial({color:0xffff00,depthFunc:THREE.AlwaysDepth,transparent:true})
    };
    static materialLineBottom = new THREE.LineBasicMaterial({color:0x666600,depthTest:true});

    static areaDatas = null;
    static areaDataMouseHover = null;
    static areaDataSelected = null;


    static Click(areaData){
        if(this.areaDataSelected == areaData){
            return;
        }

        if(this.areaDataSelected)
            this.areaDataSelected.unselect();
        if(areaData != null)
            areaData.select();
        this.areaDataSelected = areaData;
    }

    static MouseHover(areaData){
        if(this.areaDataMouseHover == areaData){
            if(areaData != null)
                areaData.mouseHover;
            return;
        }

        if(this.areaDataMouseHover)
            this.areaDataMouseHover.mouseLeave();
        if(areaData != null)
            areaData.mouseEnter();
        this.areaDataMouseHover = areaData;
    }

    static BindAnimateEvent(){
        AnimateEvents.Add(this.next);
    }

    static next(){
        MyMap.updateMaterialUniforms();
    }

    static updateMaterialUniforms(){
        let areaDatas = MyMap.areaDatas;
        let _time = Date.now() % 100000 / 1000;
        for(let k in areaDatas){
            if(areaDatas[k].IsUseCircle){
                areaDatas[k].mesh.children[0].material.uniforms._time.value = _time;
            }
        }
    }

}
class UI{
    static THREE = THREE;
    static ctx = null;
    static canvas = null;
    static styleData = {
        backgroundColor:"rgba(32,64,128,.5)",
        // backgroundColor:"rgba(32,64,128,1)",
        borderColor:"rgba(127,127,127,0.7)",
        borderPadding:1,
        borderLineWidth:2,
        fontColor:"rgba(255,255,255,.9)",
        title:"30px Verdan ",
        content:"15px Verdan",
    };
    static CreateUI(){
        let canvas = document.createElement(`canvas`);
        this.canvas = canvas;
        this.ctx = canvas.getContext(`2d`);
        
        canvas.width = 440;
        canvas.height = 130;
        canvas.style=`position: fixed; z-index: 999; left: 0; top: 0;`;

        document.body.appendChild(canvas); // TODO: delete
        // this.SetUIContext(); // TODO: 加参数
    }

    static SetUIContext(areaData){ // TODO: 加参数
        let describe = areaData.describe;
        let describeUnit = areaData.describeUnit;

        let paddingTop0 = 20;
        let paddingTop = 40 + paddingTop0;
        let paddingLeft = 20;
        let lineHeight = 20;
        let rowIndex = 0;
        let ctx = this.ctx;

        this.SetBackground();
        ctx.fillStyle = this.styleData.fontColor;
        ctx.font = this.styleData.title;
        ctx.textBaseline="top";
        ctx.fillText(describe.name, paddingLeft, paddingTop0);

        ctx.font = this.styleData.content;
        ctx.fillText(`人口: ${~~describe["人口"]}`, paddingLeft, paddingTop + lineHeight * rowIndex);
        ctx.fillText(`${describeUnit["人口"]}`, paddingLeft+80, paddingTop + lineHeight * rowIndex++);

        ctx.fillText(`面积: ${~~describe["面积"]}`, paddingLeft, paddingTop + lineHeight * rowIndex);
        ctx.fillText(`${describeUnit["面积"]}`, paddingLeft+80, paddingTop + lineHeight * rowIndex);
        ctx.fillText(`人均占地面积: ${(describe["面积"]*1000**2/describe["人口"]/10000).toFixed(2)}`, paddingLeft+180, paddingTop + lineHeight * rowIndex);
        ctx.fillText(`平米/人`, paddingLeft+340, paddingTop + lineHeight * rowIndex++);

        ctx.fillText(`GDP: ${~~describe["地区生产总值"]}`, paddingLeft, paddingTop + lineHeight * rowIndex);
        ctx.fillText(`${describeUnit["地区生产总值"]}`, paddingLeft+80, paddingTop + lineHeight * rowIndex);
        ctx.fillText(`人均GDP: ${(describe["地区生产总值"]*10000**2/describe["人口"]/10000).toFixed(2)}`, paddingLeft+180, paddingTop + lineHeight * rowIndex);
        ctx.fillText(`元/人`, paddingLeft+340, paddingTop + lineHeight * rowIndex++);
        // ctx.fillText(``);
    }

    static SetBackground(){
        let ctx = this.ctx;
        let canvas = this.canvas;
        ctx.clearRect( 0, 0, canvas.width, canvas.height);
        ctx.fillStyle = this.styleData.backgroundColor;
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        ctx.strokeStyle = this.styleData.borderColor;
        ctx.lineWidth = this.styleData.borderLineWidth;

        let width = this.styleData.borderLineWidth; // 线框
        let pad = this.styleData.borderPadding; // 边距
        ctx.strokeRect( pad+width/2, pad+width/2, canvas.width-pad*2-width, canvas.height-pad*2-width);
    }


    static styleData2 = {
        backgroundColor:"rgba(32,32,32,.5)",
        // backgroundColor:"rgba(32,64,128,1)",
        fontColor:"rgba(255,255,255,1)",
        content:"24px 微软雅黑 bold ",
        spriteSize: 0.8,
        width: 128,
        height: 32,
    };
    static canvas2 = null;
    static ctx2 = null;
    static ctx2Row = 0;
    static CreateUI2(){
        let canvas = document.createElement(`canvas`);
        this.canvas2 = canvas;
        this.ctx2 = canvas.getContext(`2d`);
        
        canvas.width = 128;
        canvas.height = 32*16;
        canvas.style=`position: fixed; z-index: 999; left: 0; top: 150px; background: #fff`;

    }
    static SetTitle(areaData){
        let ctx2Row = this.ctx2Row;
        if (this.ctx == null)
            this.CreateUI2();
        let ctx = this.ctx2;
        ctx.font = this.styleData2.content;
        ctx.fillStyle = this.styleData2.backgroundColor;
        let width = this.styleData2.width;
        let height = this.styleData2.height;

        // ctx.clearRect(0,0,128,128);
        ctx.fillRect(width*0,height*ctx2Row,width,height);
        ctx.fillStyle = this.styleData2.fontColor;
        ctx.textBaseline = "middle";
        ctx.textAlign = "center";
        let str = areaData.name;
        str = str.split("").join(" ");
        ctx.fillText(str,width*(0+.5),height*(ctx2Row+.5)+2,width,height);

        let result = this.Canvas2GL(areaData)
        this.ctx2Row++;
        return result;
    }
    static SetBackground2(){
        let ctx = this.ctx;
        ctx.strokeRect( pad+width/2, pad+width/2, canvas.width-pad*2-width, canvas.height-pad*2-width);
    }

    static Canvas2GL(areaData){
        let texture = new THREE.CanvasTexture(this.canvas2);
        // texture.wrapS =3.5;
        texture.offset.y = 1-(this.ctx2Row+1)/16;
        texture.repeat.y = 1/16;
        // texture.needsUpdate =false;
        let material = new THREE.SpriteMaterial({
            map: texture,
            sizeAttenuation: false,
            depthTest:false,
        });
        let sprite= new THREE.Sprite(material);
        sprite.scale.set(0.08*this.styleData2.spriteSize,0.02*this.styleData2.spriteSize,1);
        sprite.position.set(areaData.properties.center[0], 0, -areaData.properties.center[1]);
        window.scene.add(sprite);
        return sprite;
    }
}

MyMap.BindAnimateEvent();
// document.body.addEventListener
export {MyMap, AreaData, UI}